home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / CDROM / CDROM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-03  |  22.8 KB  |  875 lines

  1. /*                          CDROM AUDIO ROUTINES
  2.                   By Barry Egerter
  3.  
  4.              Written September 24, 1994
  5.  
  6.               Using Watcom C/C++ 10.0
  7.  
  8.           Code : FREEWARE - alter and use at will.
  9.  
  10.  
  11.            Internet Email:      barry.egerter@softnet.com
  12. */
  13. #include <dos.h>
  14. #include <io.h>
  15. #include <mem.h>
  16.  
  17. #define CDROM 0x21
  18. #define EJECT_TRAY 0
  19. #define RESET 2
  20. #define CLOSE_TRAY 5
  21. #define MEDIA_CHANGE 9
  22. #define BUSY  512
  23. #define TRACK_MASK 208
  24.  
  25. typedef struct playinfo {
  26.   unsigned char control;
  27.   unsigned char adr;
  28.   unsigned char track;
  29.   unsigned char index;
  30.   unsigned char min;
  31.   unsigned char sec;
  32.   unsigned char frame;
  33.   unsigned char zero;
  34.   unsigned char amin;
  35.   unsigned char asec;
  36.   unsigned char aframe;
  37. };
  38.  
  39.  
  40. typedef struct volumeinfo {
  41.     unsigned char mode;
  42.     unsigned char input0;
  43.     unsigned char volume0;
  44.     unsigned char input1;
  45.     unsigned char volume1;
  46.     unsigned char input2;
  47.     unsigned char volume2;
  48.     unsigned char input3;
  49.     unsigned char volume3;
  50. };
  51.  
  52.  
  53. struct {
  54.   unsigned short drives;
  55.   unsigned char  first_drive;
  56.   unsigned short current_track;
  57.   unsigned int   track_position;
  58.   unsigned char  track_type;
  59.   unsigned char  low_audio;
  60.   unsigned char  high_audio;
  61.   unsigned char  disk_length_min;
  62.   unsigned char  disk_length_sec;
  63.   unsigned char  disk_length_frames;
  64.   unsigned int   endofdisk;
  65.   unsigned char  upc[7];
  66.   unsigned char  diskid[6];
  67.   unsigned int   status;
  68.   unsigned short error;      /* See description below */
  69. } cdrom_data;
  70.  
  71. /* CDROM_DATA.ERROR Description
  72.  
  73.   Bit 15         - Error bit
  74.   Bit 14-10      - Reserved
  75.   Bit  9         - Busy
  76.   Bit  8         - Done
  77.   Bit  7-0       - Error code (bit 15 on)
  78.  
  79. Error codes are the following:
  80.  
  81.   0  Write-protect violation
  82.   1  Unknown unit
  83.   2  Drive not ready
  84.   3  Unknown command
  85.   4  CRC error
  86.   5  Bad drive request structure length
  87.   6  Seek error
  88.   7  Unknown media
  89.   8  Sector not found
  90.   9  Printer out of paper
  91.   A  Write fault
  92.   B  Read fault
  93.   C  General failure
  94.   D  Reserved
  95.   E  Reserved
  96.   F  Invalid disk change
  97. */
  98.  
  99.  
  100. /*   Multiplex Interrupt routines
  101.      "borrowed" from Ralf Brown's MSDOS Interrupt List v4.1
  102.  
  103. short 21 - CD-ROM device driver - IOCTL INPUT
  104.     AX = 4402h
  105.     BX = file handle referencing character device for CD-ROM driver
  106.     CX = number of bytes to read
  107.     DS:DX -> control block (see #0563)
  108. Return: CF clear if successful
  109.         AX = number of bytes actually read
  110.     CF set on error
  111.         AX = error code (01h,05h,06h,0Dh) (see #0770 at AH=59h)
  112. Note:   the data returned depends on the first byte of the control block; the
  113.       remainder of the control block is filled by the driver
  114. SeeAlso: AX=4403h"CD-ROM",short 2F/AX=0802h
  115.  
  116. (Table 0562)
  117. Values for CD-ROM data being requested:
  118.  00h    device driver header address
  119.  01h    drive head location
  120.  02h    reserved
  121.  03h    error statistics
  122.  04h    audio channel info
  123.  05h    raw drive bytes (uninterpreted and device-specific)
  124.  06h    device status
  125.  07h    sector size
  126.  08h    volume size
  127.  09h    media change status
  128.  0Ah    audio disk info
  129.  0Bh    audio track info
  130.  0Ch    audio Q-Channel info
  131.  0Dh    audio sub-channel info
  132.  0Eh    UPC code
  133.  
  134. Format of CD-ROM control block:
  135. Offset  Size    Description     (Table 0563)
  136.  00h    BYTE    data being requested (see #0562)
  137. ---function 00h---
  138.  01h    DWORD   device driver header address (see also AH=52h)
  139. ---function 01h---
  140.  01h    BYTE    addressing mode
  141.         00h HSG
  142.         01h Red Book
  143.  02h    DWORD   current location of drive's head
  144.         logical sector number in HSG mode
  145.         frame/second/minute/unused in Red Book mode
  146.         (HSG sector = minute * 4500 + second * 75 + frame - 150)
  147. ---function 03h---
  148.  01h  N BYTEs   undefined as of 5 Aug 88 specification
  149. ---function 04h---
  150.  01h    BYTE    input channel (0-3) for output channel 0
  151.  02h    BYTE    volume for output channel 0
  152.  03h    BYTE    input channel (0-3) for output channel 1
  153.  04h    BYTE    volume for output channel 1
  154.  05h    BYTE    input channel (0-3) for output channel 2
  155.  06h    BYTE    volume for output channel 2
  156.  07h    BYTE    input channel (0-3) for output channel 3
  157.  08h    BYTE    volume for output channel 3
  158. Notes:  output channels 0 and 1 are left and right, 2 and 3 are left prime and
  159.       right prime; a volume of 00h is off
  160.     the default setting is for each input channel to be assigned to the
  161.       same-numbered output channel at full (FFh) volume
  162. ---function 05h---
  163.  01h    BYTE    number of bytes read
  164.  02h 128 BYTEs  buffer for drive bytes
  165. ---function 06h---
  166.  01h    DWORD   device parameters (see #0564)
  167. ---function 07h---
  168.  01h    BYTE    read mode
  169.         00h cooked
  170.         01h raw
  171.  02h    WORD    sector size in bytes
  172. ---function 08h---
  173.  01h    DWORD   volume size in sectors
  174. ---function 09h---
  175.  01h    BYTE    media change status
  176.         00h don't know
  177.         01h media unchanged
  178.         FFh media has been changed
  179. ---function 0Ah---
  180.  01h    BYTE    lowest audio track number
  181.  02h    BYTE    highest audio track number
  182.  03h    DWORD   start address of lead-out track (Red Book format)
  183. --function 0Bh---
  184.  01h    BYTE    track number (set by caller)
  185.  02h    DWORD   starting point of track (Red Book format)
  186.  06h    BYTE    track control info
  187.         bits 15,14,12: track type (notice: bits not contiguous!)
  188.             000 two audio channels, no pre-emphasis
  189.             001 two audio channels with pre-emphasis
  190.             010 data track
  191.             100 four audio channels, no pre-emphasis
  192.             101 four audio channels with pre-emphasis
  193.             other reserved
  194.         bit 13: digital copy permitted
  195. ---function 0Ch---
  196.  01h    BYTE    CONTROL and ADR byte (as received from drive)
  197.  02h    BYTE    track number
  198.  03h    BYTE    point or index
  199.  04h    BYTE    minute  \
  200.  05h    BYTE    second   > running time within track
  201.  06h    BYTE    frame   /
  202.  07h    BYTE    zero
  203.  08h    BYTE    "AMIN" or "PMIN"     \
  204.  09h    BYTE    "ASEC" or "PSEC"      > running time on disk
  205.  0Ah    BYTE    "AFRAME" or "PFRAME" /
  206. ---function 0Dh---
  207.  01h    DWORD   starting frame address (Red Book format)
  208.  05h    DWORD   transfer address
  209.  09h    DWORD   number of sectors to read
  210. Note:   copies 96 bytes of sub-channel info per sector into buffer
  211. ---function 0Eh---
  212.  01h    BYTE    CONTROL and ADR byte
  213.  02h  7 BYTEs   UPC/EAN code (13 BCD digits,low-order nybble of last byte is 0)
  214.  09h    BYTE    zero
  215.  0Ah    BYTE    "AFRAME"
  216.  
  217. Bitfields for CD-ROM device parameters:
  218. Bit(s)  Description     (Table 0564)
  219.  0      door open
  220.  1      door unlocked
  221.  2      supports raw reading in addition to cooked
  222.  3      writable
  223.  4      can play audio/video tracks
  224.  5      supports interleaving
  225.  6      reserved
  226.  7      supports prefetch requests
  227.  8      supports audio channel control
  228.  9      supports Red Book addressing in addition to HSG
  229.  10     audio is playing
  230. */
  231. static struct rminfo {
  232.     long EDI;
  233.     long ESI;
  234.     long EBP;
  235.     long reserved_by_system;
  236.     long EBX;
  237.     long EDX;
  238.     long ECX;
  239.     long EAX;
  240.     short flags;
  241.     short ES,DS,FS,GS,IP,CS,SP,SS;
  242. } RMI;
  243.  
  244. static union REGS inregs, outregs;
  245. static struct SREGS sregs;
  246. static short lowptr;
  247. static int lowptr2;
  248. static void *watptr, *watptr2;
  249.  
  250. void allocbuffers (void)
  251. {
  252.   memset (&sregs, 0, sizeof(sregs));
  253.   inregs.w.ax = 0x0100;
  254.   inregs.w.bx = 0x20;
  255.   int386x (0x31, &inregs, &outregs, &sregs);
  256.   lowptr = outregs.w.ax;
  257.   watptr = (void *)((outregs.x.eax & 0xffff) << 4);
  258.   int386x (0x31, &inregs, &outregs, &sregs);
  259.   lowptr2 = outregs.w.ax << 16;
  260.   watptr2 = (void *)((outregs.x.eax & 0xffff) << 4);
  261. }
  262.  
  263.  
  264. void device_request ()
  265. {
  266.   memset (&sregs, 0, sizeof (sregs));
  267.   memset (&RMI, 0, sizeof(RMI));
  268.   RMI.EAX = 0x00001510;
  269.   RMI.ECX = cdrom_data.first_drive;
  270.   RMI.EBX = 0;
  271.   RMI.ES = lowptr;
  272.   
  273.   inregs.w.ax = 0x0300;
  274.   inregs.h.bl = 0x2f;
  275.   inregs.h.bh = 0;
  276.   inregs.w.cx = 0;
  277.   sregs.es = FP_SEG (&RMI);
  278.   inregs.x.edi = FP_OFF (&RMI);
  279.   int386x (0x31, &inregs, &outregs, &sregs);
  280.   if (outregs.x.cflag)
  281.     printf ("DEVICE REQUEST FAILED!!!\n");
  282. }
  283.  
  284.  
  285. void red_book (unsigned int value, unsigned char *min, unsigned char *sec, unsigned char *frame)
  286. {
  287.   *frame = value & 0x000000ff;
  288.   *sec = (value & 0x0000ff00) >> 8;
  289.   *min = (value & 0x00ff0000) >> 16;
  290. }
  291.  
  292.  
  293. unsigned int hsg (unsigned int value)
  294. {
  295.   unsigned char min, sec, frame;
  296.  
  297.   red_book (value, &min, &sec, &frame);
  298.   value = (unsigned int)min * 4500;
  299.   value += (short)sec * 75;
  300.   value += frame;
  301.   value -= 150;
  302.   return value;
  303. }
  304.  
  305.  
  306. unsigned int cd_head_position (void)
  307. {
  308.   struct {
  309.     unsigned char length;
  310.     unsigned char subunit;
  311.     unsigned char comcode;
  312.     unsigned short status;
  313.     char ununsed[8];
  314.     unsigned char media;
  315.     unsigned int address;
  316.     unsigned short bytes;
  317.     unsigned short sector;
  318.     unsigned int  volid;
  319.     unsigned char unused[4];
  320.   } tray_request;
  321.  
  322.   struct {
  323.     unsigned char mode;
  324.     unsigned char adr_mode;
  325.     unsigned int address;
  326.   } head_data;
  327.  
  328.   tray_request.length = sizeof (tray_request);
  329.   tray_request.subunit = 0;
  330.   tray_request.comcode = 3;
  331.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  332.   tray_request.address = lowptr2;
  333.   tray_request.bytes = 6;
  334.   head_data.mode = 0x01;
  335.   head_data.adr_mode = 0x00;
  336.   memcpy (watptr, &tray_request, tray_request.length);
  337.   memcpy (watptr2, &head_data, 6);
  338.   device_request ();
  339.   memcpy (&tray_request, watptr, tray_request.length);
  340.   memcpy (&head_data, watptr2, 6);
  341.   cdrom_data.error = tray_request.status;
  342.   return head_data.address;
  343. }
  344.  
  345.  
  346. void cd_get_volume (struct volumeinfo *vol)
  347. {
  348.   struct {
  349.     unsigned char length;
  350.     unsigned char subunit;
  351.     unsigned char comcode;
  352.     unsigned short status;
  353.     char ununsed[8];
  354.     unsigned char media;
  355.     unsigned int address;
  356.     unsigned short bytes;
  357.     unsigned short sector;
  358.     unsigned int  volid;
  359.   } tray_request;
  360.  
  361.   tray_request.length = sizeof (tray_request);
  362.   tray_request.subunit = 0;
  363.   tray_request.comcode = 3;
  364.   tray_request.media = 0;
  365.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  366.   tray_request.address = lowptr2;
  367.   tray_request.bytes = 9;
  368.   vol->mode = 0x04;
  369.   memcpy (watptr, &tray_request, sizeof (tray_request));
  370.   memcpy (watptr2, vol, sizeof (struct volumeinfo));
  371.   device_request ();
  372.   memcpy (&tray_request, watptr, tray_request.length);
  373.   memcpy (vol, watptr2, sizeof (struct volumeinfo));
  374.   cdrom_data.error = tray_request.status;
  375. }
  376.  
  377.  
  378. void cd_set_volume (struct volumeinfo *vol)
  379. {
  380.   struct {
  381.     unsigned char length;
  382.     unsigned char subunit;
  383.     unsigned char comcode;
  384.     unsigned short status;
  385.     char ununsed[8];
  386.     unsigned char media;
  387.     unsigned int address;
  388.     unsigned short bytes;
  389.     unsigned char unused[4];
  390.   } cd_request;
  391.  
  392.   vol->mode = 3;
  393.   cd_request.length = sizeof (cd_request);
  394.   cd_request.subunit = 0;
  395.   cd_request.comcode = 12;
  396.   cd_request.media = 0;
  397.   cd_request.address = lowptr2;
  398.   cd_request.bytes = 9;
  399.   memcpy (watptr, &cd_request, sizeof (cd_request));
  400.   memcpy (watptr2, vol, sizeof (struct volumeinfo));
  401.   device_request ();
  402.   memcpy (&cd_request, watptr, cd_request.length);
  403.   cdrom_data.error = cd_request.status;
  404. }
  405.  
  406.  
  407. short cd_getupc (void)
  408. {
  409.   struct {
  410.     unsigned char length;
  411.     unsigned char subunit;
  412.     unsigned char comcode;
  413.     unsigned short status;
  414.     char ununsed[8];
  415.     unsigned char media;
  416.     unsigned int address;
  417.     unsigned short bytes;
  418.     unsigned short sector;
  419.     unsigned int  volid;
  420.   } tray_request;
  421.  
  422.   struct {
  423.     unsigned char mode;
  424.     unsigned char adr;
  425.     unsigned char upc[7];
  426.     unsigned char zero;
  427.     unsigned char aframe;
  428.   } upc_data;
  429.   
  430.   tray_request.length = sizeof (tray_request);
  431.   tray_request.subunit = 0;
  432.   tray_request.comcode = 3;
  433.   tray_request.media = 0;
  434.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  435.   tray_request.address = lowptr2;
  436.   tray_request.bytes = 11;
  437.   upc_data.mode = 0x0e;
  438.   upc_data.adr = 2;
  439.   memcpy (watptr, &tray_request, sizeof (tray_request));
  440.   memcpy (watptr2, &upc_data, 11);
  441.   device_request ();
  442.   memcpy (&upc_data, watptr2, 11);
  443.   memcpy (&tray_request, watptr, tray_request.length);
  444.   cdrom_data.error = tray_request.status;
  445.   if (upc_data.adr == 0)
  446.     memset (&upc_data.upc, 0, 7);
  447.   memcpy (&cdrom_data.upc[0], &upc_data.upc[0], 7);
  448.   return 1;
  449. }
  450.  
  451.  
  452. void cd_get_audio_info (void)
  453. {
  454.   struct {
  455.     unsigned char length;
  456.     unsigned char subunit;
  457.     unsigned char comcode;
  458.     unsigned short status;
  459.     char ununsed[8];
  460.     unsigned char media;
  461.     int address;
  462.     short bytes;
  463.     short sector;
  464.     int volid;
  465.   } ioctli;
  466.  
  467.   struct {
  468.     unsigned char mode;
  469.     unsigned char lowest;
  470.     unsigned char highest;
  471.     unsigned int address;
  472.   } track_data;
  473.  
  474.   ioctli.length = sizeof (ioctli);
  475.   ioctli.subunit = 0;
  476.   ioctli.comcode = 3;
  477.   ioctli.media = 0;
  478.   ioctli.sector = 0;
  479.   ioctli.volid = 0;
  480.   ioctli.address = (unsigned int)lowptr2;
  481.   ioctli.bytes = 7;
  482.   memset (&track_data, 0, 7);
  483.   track_data.mode = 0x0a;
  484.   memcpy (watptr, &ioctli, sizeof (ioctli));
  485.   memcpy (watptr2, &track_data.mode, 7);
  486.   memcpy (&track_data, watptr2, sizeof (track_data));
  487.   device_request ();
  488.   memcpy (&track_data, watptr2, sizeof (track_data));
  489.   memcpy (&ioctli, watptr, sizeof (ioctli));
  490.   memcpy (&cdrom_data.diskid, &track_data.lowest, 6);
  491.   cdrom_data.low_audio = track_data.lowest;
  492.   cdrom_data.high_audio = track_data.highest;
  493.   red_book (track_data.address, &cdrom_data.disk_length_min, &cdrom_data.disk_length_sec, &cdrom_data.disk_length_frames);
  494.   cdrom_data.endofdisk = hsg (track_data.address);
  495.   cdrom_data.error = ioctli.status;
  496. }
  497.  
  498.  
  499. void cd_set_track (short tracknum)
  500. {
  501.   struct {
  502.     unsigned char length;
  503.     unsigned char subunit;
  504.     unsigned char comcode;
  505.     unsigned short status;
  506.     char ununsed[8];
  507.     unsigned char media;
  508.     unsigned int address;
  509.     unsigned short bytes;
  510.     unsigned short sector;
  511.     unsigned int  volid;
  512.   } tray_request;
  513.  
  514.   struct {
  515.     unsigned char mode;
  516.     unsigned char track;
  517.     unsigned int address;
  518.     unsigned char control;
  519.   } track_data;
  520.  
  521.   tray_request.length = sizeof (tray_request);
  522.   tray_request.subunit = 0;
  523.   tray_request.comcode = 3;
  524.   tray_request.media = 0;
  525.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  526.   tray_request.address = lowptr2;
  527.   tray_request.bytes = 7;
  528.   track_data.mode = 0x0b;
  529.   track_data.track = tracknum;
  530.   memcpy (watptr, &tray_request, sizeof (tray_request));
  531.   memcpy (watptr2, &track_data, sizeof (track_data));
  532.   device_request ();
  533.   memcpy (&tray_request, watptr, sizeof (tray_request));
  534.   memcpy (&track_data, watptr2, sizeof (track_data));
  535.   cdrom_data.error = tray_request.status;
  536.   cdrom_data.track_position = hsg (track_data.address);
  537.   cdrom_data.current_track = tracknum;
  538.   cdrom_data.track_type = track_data.control & TRACK_MASK;
  539. }
  540.  
  541.  
  542. unsigned int get_track_length (short tracknum)
  543. {
  544.   unsigned int start, finish;
  545.   unsigned short ct;
  546.  
  547.   ct = cdrom_data.current_track;
  548.   cd_set_track (tracknum);
  549.   start = cdrom_data.track_position;
  550.   if (tracknum < cdrom_data.high_audio)
  551.   {
  552.     cd_set_track (tracknum+1);
  553.     finish = cdrom_data.track_position;
  554.   }
  555.   else finish = cdrom_data.endofdisk;
  556.  
  557.   cd_set_track (ct);
  558.  
  559.   finish -= start;
  560.   return finish;
  561. }
  562.  
  563.  
  564. void cd_track_length (short tracknum, unsigned char *min, unsigned char *sec, unsigned char *frame)
  565. {
  566.   unsigned int value;
  567.  
  568.   value = get_track_length (tracknum);
  569.   value -= 150;
  570.   *frame = value % 75;
  571.   value -= *frame;
  572.   value /= 75;
  573.   *sec = value % 60;
  574.   value -= *sec;
  575.   value /= 60;
  576.   *min = value;
  577. }
  578.  
  579.  
  580. void cd_status (void)
  581. {
  582.   struct {
  583.     unsigned char length;
  584.     unsigned char subunit;
  585.     unsigned char comcode;
  586.     unsigned short status;
  587.     char ununsed[8];
  588.     unsigned char media;
  589.     unsigned int address;
  590.     unsigned short bytes;
  591.     unsigned short sector;
  592.     unsigned int  volid;
  593.   } tray_request;
  594.  
  595.   struct {
  596.     unsigned char mode;
  597.     unsigned int status;
  598.   } cd_data;
  599.  
  600.   tray_request.length = sizeof (tray_request);
  601.   tray_request.subunit = 0;
  602.   tray_request.comcode = 3;
  603.   tray_request.media = 0;
  604.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  605.   tray_request.address = lowptr2;
  606.   tray_request.bytes = 5;
  607.  
  608.   cd_data.mode = 0x06;
  609.   memcpy (watptr, &tray_request, sizeof (tray_request));
  610.   memcpy (watptr2, &cd_data, sizeof (cd_data));
  611.   device_request ();
  612.   memcpy (&tray_request, watptr, sizeof (tray_request));
  613.   memcpy (&cd_data, watptr2, sizeof (cd_data));
  614.   cdrom_data.status = cd_data.status;
  615.   cdrom_data.error = tray_request.status;
  616. }
  617.  
  618.  
  619. void cd_seek (unsigned int location)
  620. {
  621.   unsigned char min, sec, frame;
  622.   struct {
  623.     unsigned char length;
  624.     unsigned char subunit;
  625.     unsigned char comcode;
  626.     unsigned short status;
  627.     char ununsed[8];
  628.     unsigned char addressmode;
  629.     unsigned int transfer;
  630.     unsigned short sectors;
  631.     unsigned int seekpos;
  632.   } play_request;
  633.  
  634.   play_request.length = sizeof (play_request);
  635.   play_request.subunit = 0;
  636.   play_request.comcode = 131;
  637.   play_request.addressmode = 0;
  638.   play_request.transfer = 0;
  639.   play_request.sectors = 0;
  640.   play_request.seekpos = location;
  641.   memcpy (watptr, &play_request, sizeof (play_request));
  642.   device_request ();
  643.   memcpy (&play_request, watptr, sizeof (play_request));
  644.   cdrom_data.error = play_request.status;
  645. }
  646.  
  647.  
  648. void cd_play_audio (unsigned int begin, unsigned int end)
  649. {
  650.   unsigned int leng;
  651.  
  652.   struct {
  653.     unsigned char length;
  654.     unsigned char subunit;
  655.     unsigned char comcode;
  656.     unsigned short status;
  657.     char ununsed[8];
  658.     unsigned char addressmode;
  659.     unsigned int start;
  660.     unsigned int playlength;
  661.   } play_request;
  662.  
  663.   play_request.length = sizeof (play_request);
  664.   play_request.subunit = 0;
  665.   play_request.comcode = 132;
  666.   play_request.addressmode = 0;
  667.   play_request.start = begin;
  668.   play_request.playlength = end-begin;
  669.   memcpy (watptr, &play_request, sizeof (play_request));
  670.   device_request ();
  671.   memcpy (&play_request, watptr, sizeof (play_request));
  672.   cdrom_data.error = play_request.status;
  673. }
  674.  
  675.  
  676. void cd_stop_audio (void)
  677. {
  678.   struct {
  679.     unsigned char length;
  680.     unsigned char subunit;
  681.     unsigned char comcode;
  682.     unsigned short status;
  683.     char ununsed[8];
  684.   } stop_request;
  685.  
  686.   stop_request.length = sizeof (stop_request);
  687.   stop_request.subunit = 0;
  688.   stop_request.comcode = 133;
  689.   memcpy (watptr, &stop_request, sizeof (stop_request));
  690.   device_request ();
  691.   memcpy (&stop_request, watptr, sizeof (stop_request));
  692.   cdrom_data.error = stop_request.status;
  693. }
  694.  
  695.  
  696. void cd_resume_audio (void)
  697. {
  698.   struct {
  699.     unsigned char length;
  700.     unsigned char subunit;
  701.     unsigned char comcode;
  702.     unsigned short status;
  703.     char ununsed[8];
  704.   } stop_request;
  705.  
  706.   stop_request.length = sizeof (stop_request);
  707.   stop_request.subunit = 0;
  708.   stop_request.comcode = 136;
  709.   memcpy (watptr, &stop_request, sizeof (stop_request));
  710.   device_request ();
  711.   memcpy (&stop_request, watptr, sizeof (stop_request));
  712.   cdrom_data.error = stop_request.status;
  713. }
  714.  
  715.  
  716. void cd_cmd (unsigned char mode)
  717. {
  718.   struct {
  719.     unsigned char length;
  720.     unsigned char subunit;
  721.     unsigned char comcode;
  722.     unsigned short status;
  723.     char ununsed[8];
  724.     unsigned char media;
  725.     unsigned int address;
  726.     unsigned short bytes;
  727.     unsigned char unused[4];
  728.   } tray_request;
  729.  
  730.   unsigned char cd_mode;
  731.  
  732.   cd_mode = mode;
  733.   tray_request.length = sizeof (tray_request);
  734.   tray_request.subunit = 0;
  735.   tray_request.comcode = 12;
  736.   tray_request.media = 0;
  737.   tray_request.address = lowptr2;
  738.   tray_request.bytes = 1;
  739.   memcpy (watptr, &tray_request, sizeof (tray_request));
  740.   memcpy (watptr2, &cd_mode, 1);
  741.   device_request ();
  742.   memcpy (&tray_request, watptr, sizeof (tray_request));
  743.   cdrom_data.error = tray_request.status;
  744. }
  745.  
  746.  
  747. void cd_getpos (struct playinfo *info)
  748. {
  749.   struct {
  750.     unsigned char length;
  751.     unsigned char subunit;
  752.     unsigned char comcode;
  753.     unsigned short status;
  754.     char ununsed[8];
  755.     unsigned char media;
  756.     unsigned int address;
  757.     unsigned short bytes;
  758.     unsigned short sector;
  759.     unsigned int  volid;
  760.   } tray_request;
  761.  
  762.   tray_request.length = sizeof (tray_request);
  763.   tray_request.subunit = 0;
  764.   tray_request.comcode = 3;
  765.   tray_request.media = 0;
  766.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  767.   tray_request.address = lowptr2;
  768.   tray_request.bytes = 6;
  769.   info->control = 12;
  770.   memcpy (watptr, &tray_request, sizeof (tray_request));
  771.   memcpy (watptr2, info, sizeof (struct playinfo));
  772.   device_request ();
  773.   memcpy (&tray_request, watptr, sizeof (tray_request));
  774.   memcpy (info, watptr2, sizeof (struct playinfo));
  775.   cdrom_data.error = tray_request.status;
  776. }
  777.  
  778.  
  779. short cdrom_installed (void)
  780. {
  781.   inregs.h.ah = 0x15;
  782.   inregs.h.al = 0x00;
  783.   inregs.w.bx = 0;
  784.   int386 (0x2f, &inregs, &outregs);
  785.   if (outregs.w.bx == 0)
  786.     return (0);
  787.   cdrom_data.drives = outregs.w.bx;
  788.   cdrom_data.first_drive = outregs.w.cx;
  789.   if (lowptr == 0)
  790.     allocbuffers ();
  791.   cd_get_audio_info ();
  792.   return (1);
  793. }
  794.  
  795.  
  796. short cd_done_play (void)
  797. {
  798.   cd_cmd (CLOSE_TRAY);
  799.   return ((cdrom_data.error & BUSY) == 0);
  800. }
  801.  
  802.  
  803. short cd_mediach (void)
  804. {
  805.   struct {
  806.     unsigned char length;
  807.     unsigned char subunit;
  808.     unsigned char comcode;
  809.     unsigned short status;
  810.     char ununsed[8];
  811.     unsigned char media;
  812.     unsigned int address;
  813.     unsigned short bytes;
  814.     unsigned short sector;
  815.     unsigned int  volid;
  816.   } tray_request;
  817.  
  818.   struct {
  819.     unsigned char mode;
  820.     unsigned char media;
  821.   } cd_data;
  822.  
  823.   tray_request.length = sizeof (tray_request);
  824.   tray_request.subunit = 0;
  825.   tray_request.comcode = 3;
  826.   tray_request.media = 0;
  827.   tray_request.media = tray_request.sector = tray_request.volid = 0;
  828.   tray_request.address = lowptr2;
  829.   tray_request.bytes = 2;
  830.  
  831.   cd_data.mode = 0x09;
  832.   memcpy (watptr, &tray_request, sizeof (tray_request));
  833.   memcpy (watptr2, &cd_data, sizeof (cd_data));
  834.   device_request ();
  835.   memcpy (&tray_request, watptr, sizeof (tray_request));
  836.   memcpy (&cd_data, watptr2, sizeof (cd_data));
  837.   cdrom_data.error = tray_request.status;
  838.   return cd_data.media;
  839. }
  840.  
  841.  
  842. void cd_lock (unsigned char doormode)
  843. {
  844.   struct {
  845.     unsigned char length;
  846.     unsigned char subunit;
  847.     unsigned char comcode;
  848.     unsigned short status;
  849.     char ununsed[8];
  850.     unsigned char media;
  851.     unsigned int address;
  852.     unsigned short bytes;
  853.     unsigned char unused[4];
  854.   } tray_request;
  855.  
  856.   struct {
  857.     unsigned char mode;
  858.     unsigned char media;
  859.   } cd_data;
  860.  
  861.   tray_request.length = sizeof (tray_request);
  862.   tray_request.subunit = 0;
  863.   tray_request.comcode = 12;
  864.   tray_request.media = 0;
  865.   tray_request.address = lowptr2;
  866.   tray_request.bytes = 2;
  867.   cd_data.mode = 1;
  868.   cd_data.media = doormode;
  869.   memcpy (watptr, &tray_request, sizeof (tray_request));
  870.   memcpy (watptr2, &cd_data, sizeof (cd_data));
  871.   device_request ();
  872.   memcpy (&tray_request, watptr, sizeof (tray_request));
  873.   cdrom_data.error = tray_request.status;
  874. }
  875.